package collisions 
{
	import com.demonsters.debugger.MonsterDebugger;
	/**
	 * ...
	 * @author Gareth Williams
	 * static class for pooling objects
	 * the functionality is inlined wherever possible to maintain the performance gain from this class
	 */
	public final class QuadTreePool
	{
		//linked list for pool
		public static var poolHead:DoubleLinkedList = new DoubleLinkedList(null, null);
		public static var poolTail:DoubleLinkedList = poolHead;
		
		private static var maximumSize:int;//after which the pool is static
		private static var minimumSize:int;//below which the pool is filled
		private static var currentSize:int = 0;
		
		private static var isInitialised:Boolean = false;
		
		private static function initialisePool(toSize:int = 800, minimumSize:int = 100):void
		{
			QuadTreePool.maximumSize = toSize;
			QuadTreePool.minimumSize = minimumSize;
			
			poolTail = poolHead;
			while (currentSize < toSize) //watch out for zeroth element
			{
				poolTail.next = new DoubleLinkedList(null, poolTail);
				poolTail = poolTail.next;
				poolTail.object = new QuadTree(0, 0, Constants.SCREEN_WIDTH, Constants.SCREEN_HEIGHT);
				currentSize++;
			}
			isInitialised = true;
		}
		
		//'factory' interface
		public static function checkOut(x:int, y:int, width:int, height:int, parent:QuadTree = null):QuadTree
		{
			//initialise
			if (false == isInitialised) initialisePool();
			
			//fill the pool up if it is too small
			if (currentSize <= minimumSize)
			{
				MonsterDebugger.log("QuadTreePool::checkout - filling pool");
				while (currentSize < maximumSize)
				{
					poolTail.next = new DoubleLinkedList(null, poolTail);
					poolTail = poolTail.next;
					poolTail.object = new QuadTree(0, 0, Constants.SCREEN_WIDTH, Constants.SCREEN_HEIGHT);
					currentSize++;
				}
			}
			
			//initialise the tree
			var tree:QuadTree = poolTail.object as QuadTree;
			tree.x = x;
			tree.y = y;
			tree.width = width;
			tree.height = height;
			tree.parent = parent;
			
			//slice element from list
			poolTail.object = null;
			var previousLink:DoubleLinkedList = poolTail.previous;
			var nextLink:DoubleLinkedList = poolTail.next;
			poolTail = previousLink;
			poolTail.next = nextLink;
			currentSize--;
			return tree;
		}
		//clean and recycle tree
		public static function checkIn(tree:QuadTree):void
		{
			//initialise
			if (false == isInitialised) initialisePool();
			
			//shortcut early if the pool is too big
			if (currentSize >= maximumSize) return;
			
			//clean the tree
			tree.destructor();
			
			//add to pool
			poolTail.next = new DoubleLinkedList(tree, poolTail);
			poolTail = poolTail.next;
			currentSize++;
		}
		public static function get poolSize():int
		{
			return currentSize;
		}
	}
}